package com.duobaoyu.dby.supply.admin.controller.config;

import com.alibaba.fastjson.JSON;
import com.duobaoyu.dby.channel.adapter.enums.OperationTypeEnum;
import com.duobaoyu.dby.common.core.constant.CommonConstants;
import com.duobaoyu.dby.common.core.constant.StringPool;
import com.duobaoyu.dby.common.core.util.R;
import com.duobaoyu.dby.supply.admin.annotation.SupplySysLog;
import com.duobaoyu.dby.supply.biz.client.resource.ResourceDictionaryItemAdminClient;
import com.duobaoyu.dby.supply.common.biz.dto.config.BloomFilterDTO;
import com.duobaoyu.dby.supply.core.cache.service.RedisCacheService;
import com.duobaoyu.dby.supply.core.common.exception.CustomAssert;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.connection.DataType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.Set;

/**
 * 缓存管理
 * @author liyang
 * @version 1.0.0
 * @ClassName BloomFilterController
 * @Description 布隆过滤器Controller
 * @createTime 18:50:00 2022/08/09
 */
@Validated
@RestController
@RequiredArgsConstructor
@RequestMapping("/admin/bloom-filter")
@Api(value = "bloom-filter", tags = "布隆过滤器Controller")
public class BloomFilterController {

	private final RedisCacheService redisCacheService;
	private final ResourceDictionaryItemAdminClient resourceDictionaryItemAdminClient;

	/**
	 * 全量初始化布隆过滤器
	 * @return
	 */
	@PostMapping("/initialize")
	@ApiOperation(value = "全量初始化布隆过滤器", notes = "全量初始化布隆过滤器")
	@SupplySysLog(value = "全量初始化布隆过滤器",operationType = OperationTypeEnum.UPDATE)
	public R<Boolean> initializeFull(){
		boolean result = resourceDictionaryItemAdminClient.initializeBloomFilter();
		return result ? R.ok(result) : R.failed();
	}

	/**
	 * 全量初始化布隆过滤器
	 * @param bloomFilter
	 * @return
	 */
	@PostMapping("/only/initialize")
	@ApiOperation(value = "全量初始化布隆过滤器", notes = "全量初始化布隆过滤器")
	@SupplySysLog(value = "全量初始化布隆过滤器",operationType = OperationTypeEnum.UPDATE)
	public R<Boolean> initializeFull(@Validated @RequestBody BloomFilterDTO bloomFilter){

		boolean result = resourceDictionaryItemAdminClient.initializeBloomFilter(bloomFilter.getDictionaryItemId(),bloomFilter.getExpectedInsertions(),bloomFilter.getFalseProbability());
		return result ? R.ok(result) : R.failed();
	}

	/**
	 * 查询Redis缓存Key
	 * @param keyPrefix
	 * @return
	 */
	@GetMapping("/redis-keys/{keyPrefix}")
	@ApiOperation(value = "查询Redis缓存Key", notes = "查询Redis缓存Key")
	@SupplySysLog(value = "查询Redis缓存Key",operationType = OperationTypeEnum.SELECT)
	public R<Set<String>> redisKeys(@PathVariable("keyPrefix") String keyPrefix){
		keyPrefix = StringUtils.isNotBlank(keyPrefix) ? keyPrefix : StringPool.EMPTY;
		Set<String> keys = redisCacheService.keys(keyPrefix);
		return R.ok(keys);
	}

	/**
	 * 查询Redis缓存
	 * @param key
	 * @return
	 */
	@GetMapping("/redis-value/{key}")
	@ApiOperation(value = "查询Redis缓存", notes = "查询Redis缓存")
	@SupplySysLog(value = "查询Redis缓存",operationType = OperationTypeEnum.SELECT)
	public R<Object> redisValue(@NotBlank(message = "缓存Key不能为空") @PathVariable("key") String key){
		DataType dataType = redisCacheService.keyType(key);
		Object object = null;
		switch (dataType){
			case STRING :
				object = redisCacheService.get(key);
				break;
			case SET:
				object = redisCacheService.sGet(key);
				break;
			case LIST:
				object = redisCacheService.lGet(key, CommonConstants.ZERO, CommonConstants.MENU_TREE_ROOT_ID);
				break;
			case HASH:
				object = redisCacheService.hmGet(key);
				break;
			case ZSET:
				object = redisCacheService.getZSetReverseRangeData(key, CommonConstants.ZERO, CommonConstants.MENU_TREE_ROOT_ID);
				break;
			case STREAM:
				object = redisCacheService.readStream(key);
				break;
			default:
				CustomAssert.isTrue(Boolean.FALSE,"Redis不存在的缓存Key");
		}
		if (object instanceof String) {
			return R.ok(object);
		}
		return R.ok(JSON.toJSONString(object));
	}

	/**
	 * 删除Redis缓存
	 * @param keys
	 * @return
	 */
	@PostMapping("/redis-delete")
	@ApiOperation(value = "删除Redis缓存", notes = "删除Redis缓存")
	@SupplySysLog(value = "删除Redis缓存",operationType = OperationTypeEnum.SELECT)
	public R<Object> delRedis(@RequestBody @NotEmpty(message = "缓存Key不能为空") Set<String> keys){
		boolean del = redisCacheService.del(keys.stream().toArray(String[]::new));
		return R.ok(del);
	}
}
